const fs = require("fs");
const path = require("path");

class JsonConfigFile{
    
    /**
     * @description: 
     * @param {string} filePath 路径以项目路径为根
     * @param {string} default_data
     * @return {*}
     */
    constructor(filePath, default_data='{}'){
        this.filePath = path.resolve(filePath);
        this.writeTimer = null;
        this.pendingWrites = 0;

        if (!fs.existsSync(filePath)){
            this.json = JSON.parse(default_data);
            fs.mkdirSync(path.dirname(filePath), {recursive: true});
            this.writeAllSync(this.json);
        }else{
            this.json = this.readAllParse();
        }
    }
    
    get(key){
        return this.json[key];
    }

    set(key, value){
        this.json[key] = value;
        this.pendingWrites++;
        return this.scheduleWrite();
    }

    read(){
        return fs.readFileSync(this.filePath);
    }

    readAllParse(){
        let res;
        try{
            res = JSON.parse(fs.readFileSync(this.filePath));
        }catch(err) {
            res = null;
            console.error(err);
        }
        return res;
    }

    writeAllSync(data){
        if (typeof(data) == 'string'){
            this.json = JSON.parse(data);
            return fs.writeFileSync(this.filePath, data);
        }else{
            this.json = data;
            return fs.writeFileSync(this.filePath, JSON.stringify(data, null, 4));
        }
    }

    // 调度写入 - 防抖机制实现
    async scheduleWrite() {
        // 清除现有定时器（重置等待时间）
        clearTimeout(this.writeTimer);
        
        // 创建新的写入任务承诺
        return new Promise((resolve) => {
            // 设置300ms防抖窗口
            this.writeTimer = setTimeout(async () => {
                try {
                    await this.writeAllAsync(this.json);
                    this.pendingWrites = 0;
                    resolve(true);
                } catch(err) {
                    console.error('写入文件失败:\n', err.message+'\n'+err.stack);
                    resolve(false);
                }
            }, 300);
        });
    }
    
    // 异步写入方法
    async writeAllAsync(data) {
        const content = typeof data === 'string' 
            ? data 
            : JSON.stringify(data, null, 4);
        
        // 使用异步API写入文件
        await fs.promises.writeFile(this.filePath, content);
        
        // 更新内存中的JSON引用
        this.json = typeof data === 'string' ? JSON.parse(data) : data;
    }
}

module.exports = JsonConfigFile;